<?php
namespace app\wechatmp\controller;
use think\facade\Cache;
use think\facade\Session;
use think\facade\Db;
use think\helper\Str;
use think\Response;
use think\exception\HttpResponseException;
use app\common\model\UserWx as UserWxModel;
use app\common\model\User as UserModel;
use app\common\model\UserTimer as UserTimerModel;
use app\common\model\UserLoginLog as UserLoginLogModel;
use app\common\model\UserDevices as UserDevicesModel;
use helper\URL;
use helper\Wechat;
class Index extends Base
{
    public $H5Url='';
    public $H5UrlFial='';
    public $H5UrlSuccess='';
    /**
     * [__construct 构造函数]
     * @return [type] [description]
     */
    public function __construct(){
        $this->H5Url=config('web.h5');
        $this->H5UrlSuccess=config('web.h5').'/#/pages/common/home/home';
        $this->H5UrlFial=config('web.h5').'/#/pages/common/login/login';
    }
    public function login()
    {
        $G=request()->get();
    	if(!empty($G['state'])){
            switch($G['state']){
                case 'hasUserSns':
                return $this->hasUserSns();
                case 'hasUser':
                return $this->hasUser();
            }
        }
        $this->authorization();
    }
    /**
     * [authorization 获取GET的code代码]
     * @return [type] [description]
     */
    public function authorization()
    {
        $appid=config('xy_wechat_mp.appid');
        $redirect_uri = urlencode(config('web.wechatmp').'/login');
        $url ="https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=$redirect_uri&response_type=code&scope=snsapi_base&state=hasUser#wechat_redirect";
        throw new HttpResponseException(Response::create($url,'redirect',302));
    }
    /**
     * 获取OpenId
     */
    public function hasUser()
    {
        $G=request()->get();
        if(empty($G['code'])){
            throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
        }
        $param=[
            'appid'     =>  config('xy_wechat_mp.appid'),
            'secret'    =>  config('xy_wechat_mp.secret'),
            'code'      =>  $G['code'],
            'grant_type'=>  'authorization_code'
        ];
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token";
        $jsonarr = json_decode(URL::get($url,$param), true);
        if(empty($jsonarr['openid'])){
            throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
        }
        return $this->getUserInfo($jsonarr['openid']);
    }
    /**
     * 获取用户信息
     */
    public function getUserInfo($openid)
    {
        Session::delete('WechatId');
        $wxInfo=Wechat::getUserInfo($openid);
        if(empty($wxInfo['subscribe']))
            throw new HttpResponseException(Response::create(config('web.h5').'/login/wx','redirect',302));
        if(empty($wxInfo['unionid'])){
            throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
        }
        $UserWxModel=UserWxModel::where(['wx_openid'=>$openid])->find();
        if(!$UserWxModel||!$UserWxModel->uid){
            $UserWxModel=UserWxModel::where(['unionid'=>$wxInfo['unionid']])->find();
        }
        //设置所有使用微信登陆的用户默认为已订阅
        $wxInfo['subscribe']=1;
        $uid=Session::get('User.id');
        if($uid){
            if ($UserWxModel) {
                if($UserWxModel->uid
                    &&$UserWxModel->uid!==$uid)
                throw new HttpResponseException(Response::create($this->H5Url.'/#/pages/common/member/action/bind?wxerr=该微信已绑定用户','redirect',302));
            }else{
                $UserWxModel=new UserWxModel;
            }
            $UserWxModel->uid           =   $uid;
            $UserWxModel->nickname      =   base64_encode($wxInfo['nickname']);
            $UserWxModel->wx_openid     =   $wxInfo['openid'];
            $UserWxModel->unionid       =   $wxInfo['unionid'];
            $UserWxModel->sex           =   $wxInfo['sex'];
            $UserWxModel->headimgurl    =   $wxInfo['headimgurl'];
            $UserWxModel->city          =   $wxInfo['city'];
            $UserWxModel->province      =   $wxInfo['province'];
            $UserWxModel->country       =   $wxInfo['country'];
            $UserWxModel->subscribe     =   $wxInfo['subscribe'];
            if ($UserWxModel->save()) {
                $UserInfo=UserModel::getAppUserInfo(['user.id'=>$UserWxModel->uid]);
                $this->setSuccessLogin($UserInfo);
                throw new HttpResponseException(Response::create($this->H5Url.'/#/pages/common/member/action/bind','redirect',302));
            }else{
                throw new HttpResponseException(Response::create($this->H5Url.'/#/pages/common/member/action/bind?wxerr=更新用户信息失败，请重试','redirect',302));
            }
        }else{
            if ($UserWxModel) {
                if($UserWxModel->uid){
                    $UserWxModel->nickname      =   base64_encode($wxInfo['nickname']);
                    $UserWxModel->wx_openid     =   $wxInfo['openid'];
                    $UserWxModel->sex           =   $wxInfo['sex'];
                    $UserWxModel->headimgurl    =   $wxInfo['headimgurl'];
                    $UserWxModel->city          =   $wxInfo['city'];
                    $UserWxModel->province      =   $wxInfo['province'];
                    $UserWxModel->country       =   $wxInfo['country'];
                    $UserWxModel->subscribe     =   $wxInfo['subscribe'];
                    $UserWxModel->save();
                    $UserInfo=UserModel::getAppUserInfo(['user.id'=>$UserWxModel->uid]);
                    if (!$UserInfo)
                        throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
                    if (!$UserInfo['status'])
                        throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
                    $UserTimer = UserTimerModel::where(['uid'=>$UserInfo['id']])->find();
                    $UserTimer->online_time=time();
                    $UserTimer->online_ip=request()->ip();
                    $UserTimer->online_devices=request()->header('xycms-deviceid');
                    $UserTimer->login_time=time();
                    $UserTimer->login_ip=request()->ip();
                    $UserTimer->login_devices=request()->header('xycms-deviceid');
                    $UserLoginLog=new UserLoginLogModel;
                    $UserLoginLog->uid=$UserInfo->id;
                    $UserLoginLog->appid=request()->ApiInfo['app_id'];
                    $UserLoginLog->ip=request()->ip();
                    $UserLoginLog->devices_id=request()->header('xycms-deviceid');
                    $UserDevicesModel=null;
                    if(!UserDevicesModel::where(['uid'=>$UserInfo->id,'appid'=>request()->ApiInfo['app_id'],'devices_id'=>request()->header('xycms-deviceid')])->count()){
                        $UserDevicesModel=new UserDevicesModel;
                        $UserDevicesModel->uid=$UserInfo->id;
                        $UserDevicesModel->appid=request()->ApiInfo['app_id'];
                        $UserDevicesModel->devices_id=request()->header('xycms-deviceid');
                    }
                    Db::startTrans();
                    try {
                        $UserTimer->save();
                        $UserLoginLog->save();
                        if($UserDevicesModel)$UserDevicesModel->save();
                        Db::commit();
                        $this->setSuccessLogin($UserInfo);
                    } catch (Exception $e) {
                        Db::rollback();
                    }
                    if (Session::has('User')) {
                        throw new HttpResponseException(Response::create($this->H5UrlSuccess,'redirect',302));
                    }else{
                        throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
                    }
                }
            }else{
                $UserWxModel=new UserWxModel;
            }
            $UserWxModel->nickname      =   base64_encode($wxInfo['nickname']);
            $UserWxModel->wx_openid     =   $wxInfo['openid'];
            $UserWxModel->unionid       =   $wxInfo['unionid'];
            $UserWxModel->sex           =   $wxInfo['sex'];
            $UserWxModel->headimgurl    =   $wxInfo['headimgurl'];
            $UserWxModel->city          =   $wxInfo['city'];
            $UserWxModel->province      =   $wxInfo['province'];
            $UserWxModel->country       =   $wxInfo['country'];
            $UserWxModel->subscribe     =   $wxInfo['subscribe'];
            if ($UserWxModel->save()) {
                Session::set('WechatId',$UserWxModel->id);
                throw new HttpResponseException(Response::create($this->H5UrlFial.'?wx_id='.$UserWxModel->id.'&nickname='.$wxInfo['nickname'].'&headimgurl='.$wxInfo['headimgurl'],'redirect',302));
            }else{
                throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
            }
        }
    }
    /**
     * 获取OpenId
     */
    public function hasUserSns()
    {
        $G=request()->get();
        if(empty($G['code'])){
            throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
        }
        $param=[
            'appid'     =>  config('xy_wechat_mp.appid'),
            'secret'    =>  config('xy_wechat_mp.secret'),
            'code'      =>  $G['code'],
            'grant_type'=>  'authorization_code'
        ];
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token";
        $jsonarr = json_decode(URL::get($url,$param), true);
        if(empty($jsonarr['openid'])){
            throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
        }
        return $this->getUserInfoSns($jsonarr['openid'],$jsonarr['access_token']);
    }
    /**
     * 获取用户信息
     */
    public function getUserInfoSns($openid,$token)
    {
        Session::delete('WechatId');
        $wxInfo=Wechat::getUserInfoSns($openid,$token);
        if(empty($wxInfo['unionid'])){
            throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
        }
        $UserWxModel=UserWxModel::where(['wx_openid'=>$openid])->find();
        if(!$UserWxModel||!$UserWxModel->uid){
            $UserWxModel=UserWxModel::where(['unionid'=>$wxInfo['unionid']])->find();
        }
        $uid=Session::get('User.id');
        //设置所有使用微信登陆的用户默认为已订阅
        $wxInfo['subscribe']=1;
        if($uid){
            if ($UserWxModel) {
                if($UserWxModel->uid
                    &&$UserWxModel->uid!==$uid)
                throw new HttpResponseException(Response::create($this->H5Url.'/#/pages/common/member/action/bind?wxerr=该微信已绑定用户','redirect',302));
            }else{
                $UserWxModel=new UserWxModel;
            }
            $UserWxModel->uid           =   $uid;
            $UserWxModel->nickname      =   base64_encode($wxInfo['nickname']);
            $UserWxModel->wx_openid     =   $wxInfo['openid'];
            $UserWxModel->unionid       =   $wxInfo['unionid'];
            $UserWxModel->sex           =   $wxInfo['sex'];
            $UserWxModel->headimgurl    =   $wxInfo['headimgurl'];
            $UserWxModel->city          =   $wxInfo['city'];
            $UserWxModel->province      =   $wxInfo['province'];
            $UserWxModel->country       =   $wxInfo['country'];
            if (isset($wxInfo['subscribe']))
            $UserWxModel->subscribe     =   $wxInfo['subscribe'];
            if ($UserWxModel->save()) {
                $UserInfo=UserModel::getAppUserInfo(['user.id'=>$UserWxModel->uid]);
                $this->setSuccessLogin($UserInfo);
                throw new HttpResponseException(Response::create($this->H5Url.'/#/pages/common/member/action/bind','redirect',302));
            }else{
                throw new HttpResponseException(Response::create($this->H5Url.'/#/pages/common/member/action/bind?wxerr=更新用户信息失败，请重试','redirect',302));
            }
        }else{
            if ($UserWxModel) {
                if($UserWxModel->uid){
                    $UserWxModel->nickname      =   base64_encode($wxInfo['nickname']);
                    $UserWxModel->wx_openid     =   $wxInfo['openid'];
                    $UserWxModel->sex           =   $wxInfo['sex'];
                    $UserWxModel->headimgurl    =   $wxInfo['headimgurl'];
                    $UserWxModel->city          =   $wxInfo['city'];
                    $UserWxModel->province      =   $wxInfo['province'];
                    $UserWxModel->country       =   $wxInfo['country'];
                    if (isset($wxInfo['subscribe']))
                    $UserWxModel->subscribe     =   $wxInfo['subscribe'];
                    $UserWxModel->save();
                    $UserInfo=UserModel::getAppUserInfo(['user.id'=>$UserWxModel->uid]);
                    if (!$UserInfo)
                        throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
                    if (!$UserInfo['status'])
                        throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
                    $UserTimer = UserTimerModel::where(['uid'=>$UserInfo['id']])->find();
                    $UserTimer->online_time=time();
                    $UserTimer->online_ip=request()->ip();
                    $UserTimer->online_devices=request()->header('xycms-deviceid');
                    $UserTimer->login_time=time();
                    $UserTimer->login_ip=request()->ip();
                    $UserTimer->login_devices=request()->header('xycms-deviceid');
                    $UserLoginLog=new UserLoginLogModel;
                    $UserLoginLog->uid=$UserInfo->id;
                    $UserLoginLog->appid=request()->ApiInfo['app_id'];
                    $UserLoginLog->ip=request()->ip();
                    $UserLoginLog->devices_id=request()->header('xycms-deviceid');
                    $UserDevicesModel=null;
                    if(!UserDevicesModel::where(['uid'=>$UserInfo->id,'appid'=>request()->ApiInfo['app_id'],'devices_id'=>request()->header('xycms-deviceid')])->count()){
                        $UserDevicesModel=new UserDevicesModel;
                        $UserDevicesModel->uid=$UserInfo->id;
                        $UserDevicesModel->appid=request()->ApiInfo['app_id'];
                        $UserDevicesModel->devices_id=request()->header('xycms-deviceid');
                    }
                    Db::startTrans();
                    try {
                        $UserTimer->save();
                        $UserLoginLog->save();
                        if($UserDevicesModel)$UserDevicesModel->save();
                        Db::commit();
                        $this->setSuccessLogin($UserInfo);
                    } catch (Exception $e) {
                        Db::rollback();
                    }
                    if (Session::has('User')) {
                        throw new HttpResponseException(Response::create($this->H5UrlSuccess,'redirect',302));
                    }else{
                        throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
                    }
                }
            }else{
                $UserWxModel=new UserWxModel;
            }
            $UserWxModel->nickname      =   base64_encode($wxInfo['nickname']);
            $UserWxModel->wx_openid     =   $wxInfo['openid'];
            $UserWxModel->unionid       =   $wxInfo['unionid'];
            $UserWxModel->sex           =   $wxInfo['sex'];
            $UserWxModel->headimgurl    =   $wxInfo['headimgurl'];
            $UserWxModel->city          =   $wxInfo['city'];
            $UserWxModel->province      =   $wxInfo['province'];
            $UserWxModel->country       =   $wxInfo['country'];
            if (isset($wxInfo['subscribe']))
            $UserWxModel->subscribe     =   $wxInfo['subscribe'];
            if ($UserWxModel->save()) {
                Session::set('WechatId',$UserWxModel->id);
                throw new HttpResponseException(Response::create($this->H5UrlFial.'?wx_id='.$UserWxModel->id.'&nickname='.$wxInfo['nickname'].'&headimgurl='.$wxInfo['headimgurl'],'redirect',302));
            }else{
                throw new HttpResponseException(Response::create($this->H5UrlFial,'redirect',302));
            }
        }
    }
    public function setSuccessLogin($UserInfo)
    {
        $key=md5('Message:&'.request()->ip().'&'.$UserInfo->id.'&'.time().'&'.Str::random(8));
        $UserInfo->token=$key;
        $UserInfo->client_id=[];
        Session::set('User',$UserInfo->toArray());
        Cache::set('Message::'.$key,$UserInfo->id);
    }
}
